package com.lge.simpleeventhandler.dom;

import com.lge.simpleeventhandler.Model;
import com.lge.simpleeventhandler.Schedule;

import org.jdom2.Attribute;
import org.jdom2.Document;
import org.jdom2.Element;
import org.jdom2.JDOMException;
import org.jdom2.input.SAXBuilder;
import org.jdom2.output.Format;
import org.jdom2.output.XMLOutputter;

import java.io.File;
import java.io.FileWriter;
import java.io.IOException;
import java.util.ArrayList;
import java.util.ListIterator;

public class JDOMParser {
    public static Document document = null;
    public static ArrayList<Model> modelList = null;

    public static void loadDocumentWithFile(File xmlFile) {
        if (xmlFile == null) {
            document = new Document();

            Element rootElement = new Element("models");
            document.setRootElement(rootElement);
        } else {
            try {
                SAXBuilder saxBuilder = new SAXBuilder();
                document = (Document)saxBuilder.build(xmlFile);
            } catch (IOException ioEx) {
                ioEx.printStackTrace();
            } catch (JDOMException jdomEx) {
                jdomEx.printStackTrace();
            }
        }
    }

    public static ArrayList<Model> getModelList() {
        if (modelList == null) {
            modelList = new ArrayList<Model>();
        }
        modelList.clear();

        Element rootElement = document.getRootElement();

        for (Element modelElement : rootElement.getChildren()) {
            Model model = new Model();

            if (modelElement.getName().equals("model")) {
                model.setModelName(modelElement.getAttributeValue("name"));
                model.setModelProject(modelElement.getAttributeValue("project"));
                model.setModelOperator(modelElement.getAttributeValue("operator"));
                model.setModelCountry(modelElement.getAttributeValue("country"));

                for (Element subElement : modelElement.getChildren()) {
                    if (subElement.getName().equals("schedules")) {
                        ArrayList<Schedule> scheduleList = new ArrayList<Schedule>();

                        for (Element scheduleElement : subElement.getChildren()) {
                            if (scheduleElement.getName().equals("schedule")) {
                                Schedule schedule = new Schedule();

                                schedule.setScheduleEvent(scheduleElement.getAttributeValue("event"));
                                schedule.setScheduleStart(scheduleElement.getAttributeValue("start"));
                                schedule.setScheduleEnd(scheduleElement.getAttributeValue("end"));
                                schedule.setScheduleFixed(Boolean.valueOf(scheduleElement.getAttributeValue("fixed")));
                                schedule.setScheduleBranch(scheduleElement.getAttributeValue("branch"));
                                schedule.setScheduleBranchedout(Boolean.valueOf(scheduleElement.getAttributeValue("branchedout")));
                                schedule.setScheduleRequestcollab(scheduleElement.getAttributeValue("requestcollab"));
                                schedule.setScheduleVersion(scheduleElement.getAttributeValue("version"));

                                scheduleList.add(schedule);
                            }
                        }

                        model.setScheduleList(scheduleList);
                    } else if (subElement.getName().equals("chipset")) {
                        model.setChipsetName(subElement.getAttributeValue("name"));
                        model.setChipsetDllpath(subElement.getAttributeValue("dllpath"));
                    } else if (subElement.getName().equals("binary")) {
                        model.setBinaryDailypath(subElement.getAttributeValue("dailypath"));
                        model.setBinaryModelpath(subElement.getAttributeValue("modelpath"));
                        model.setBinaryDeveloperpath(subElement.getAttributeValue("developerpath"));
                    }
                }
            }

            modelList.add(model);
        }

        return modelList;
    }

    public static boolean removeModelElement(Model model) {
        if (!isExist(model)) {
            return false;
        }
        
        Element toRemove = null;
        
        for (Element modelElement : document.getRootElement().getChildren("model")) {
            if (modelElement.getAttribute("name").equals(model.getModelName())) {
                toRemove = modelElement;
                break;
            }
        }
        
        document.getRootElement().removeContent(toRemove);
        
        return true;
    }
    
    public static boolean addModelElement(Model model) {
        if (isExist(model)) {
            return false;
        }

        Element modelElement = new Element("model");

        ArrayList<Attribute> modelAttributes = new ArrayList<Attribute>();
        modelAttributes.add(new Attribute("name", model.getModelName()));
        modelAttributes.add(new Attribute("project", model.getModelProject()));
        modelAttributes.add(new Attribute("operator", model.getModelOperator()));
        modelAttributes.add(new Attribute("country", model.getModelCountry()));
        modelElement.setAttributes(modelAttributes);

        Element schedulesElement = new Element("schedules");
        ArrayList<Schedule> scheduleList = model.getScheduleList();

        for (Schedule schedule : scheduleList) {
            Element scheduleElement = new Element("schedule");

            ArrayList<Attribute> scheduleAttributes = new ArrayList<Attribute>();
            scheduleAttributes.add(new Attribute("event", removeNull(schedule.getScheduleEvent())));
            scheduleAttributes.add(new Attribute("start", removeNull(schedule.getScheduleStart())));
            scheduleAttributes.add(new Attribute("end", removeNull(schedule.getScheduleEnd())));
            scheduleAttributes.add(new Attribute("fixed", removeNull(String.valueOf(schedule.isScheduleFixed()))));
            scheduleAttributes.add(new Attribute("branch", removeNull(schedule.getScheduleBranch())));
            scheduleAttributes.add(new Attribute("branchedout", removeNull(String.valueOf(schedule.isScheduleBranchedout()))));
            scheduleAttributes.add(new Attribute("requestcollab", removeNull(schedule.getScheduleRequestcollab())));
            scheduleAttributes.add(new Attribute("version", removeNull(schedule.getScheduleVersion())));
            scheduleElement.setAttributes(scheduleAttributes);

            schedulesElement.addContent(scheduleElement);
        }

        Element chipsetElement = new Element("chipset");

        ArrayList<Attribute> chipsetAttributes = new ArrayList<Attribute>();
        chipsetAttributes.add(new Attribute("name", model.getChipsetName()));
        chipsetAttributes.add(new Attribute("dllpath", model.getChipsetDllpath()));
        chipsetElement.setAttributes(chipsetAttributes);

        Element binaryElement = new Element("binary");

        ArrayList<Attribute> binaryAttributes = new ArrayList<Attribute>();
        binaryAttributes.add(new Attribute("dailypath", model.getBinaryDailypath()));
        binaryAttributes.add(new Attribute("modelpath", model.getBinaryModelpath()));
        binaryAttributes.add(new Attribute("developerpath", model.getBinaryDeveloperpath()));
        binaryElement.setAttributes(binaryAttributes);

        modelElement.addContent(schedulesElement);
        modelElement.addContent(chipsetElement);
        modelElement.addContent(binaryElement);

        document.getRootElement().addContent(modelElement);

        return true;
    }
    
    public static String removeNull(String value) {
        if (value == null) {
            return "";
        } else {
            return value;
        }
    }

    public static boolean isExist(Model model) {
        if (modelList == null) {
            getModelList();
        }
        
        for (Model modelInList : modelList) {
            if (model.getModelName().equals(modelInList.getModelName())) {
                return true;
            }
        }

        return false;
    }

    public static Element getNextSibling(Element element) {
        ListIterator<Element> iterator = element.getParentElement().getChildren().listIterator();
        boolean isFinished = false;
        Element nextElement = null;

        while (iterator.hasNext() && !isFinished) {
            Element tempElement = (Element)iterator.next();

            if (element.equals(tempElement)) {
                isFinished = true;
            }
        }

        if (isFinished) {
            if (iterator.hasNext()) {
                nextElement = (Element)iterator.next();
                iterator.previous();
            }
        }

        return nextElement;
    }

    public static void saveToFile(File xmlFile) {
        try {
            XMLOutputter xmlOutput = new XMLOutputter();
            xmlOutput.setFormat(Format.getPrettyFormat().setIndent("\t"));
            xmlOutput.output(document, new FileWriter(xmlFile));
        } catch (IOException ioE) {
            ioE.printStackTrace();
        } catch (Exception e) {
            e.printStackTrace();
        }
    }
}